package com.mhy.logcat;

import android.util.LogPrinter;
import android.util.PrintWriterPrinter;
import android.util.Printer;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * port:9696
 * Local file
 * LogManager.setTarget(new File(Environment.getExternalStorageDirectory(), "traces.log"));
 * LogCat.d(TAG, "Hello log file!");
 * <p>
 * Remote server
 * LogManager.setTarget("192.168.0.10", 9696));
 * LogCat.d(TAG, "Hello log server!");
 */
class LogManager {
    private LogManager() {
    }

    private static class MyPrinter implements Printer {
        private final SocketAddress socketAddress;
        private DatagramSocket datagramSocket; // 复用socket
        private final ExecutorService threadPool = Executors.newCachedThreadPool();

        private MyPrinter(SocketAddress socketAddress) {
            this.socketAddress = socketAddress;
            try {
                this.datagramSocket = new DatagramSocket();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void println(String str) {
            threadPool.submit(new LogTask(this.datagramSocket, this.socketAddress, str));
        }
    }

    private static class LogTask implements Runnable {
        private final SocketAddress address;
        private String message = "";
        private DatagramSocket datagramSocket;

        private LogTask(DatagramSocket datagramSocket, SocketAddress socketAddress, String message) {
            this.address = socketAddress;
            this.message = message;
            if (datagramSocket == null || datagramSocket.isClosed()) {
                try {
                    this.datagramSocket = new DatagramSocket();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                this.datagramSocket = datagramSocket;
            }
        }

        @Override
        public void run() {
            // 保留原逻辑，但减少socket创建
            if (datagramSocket == null || datagramSocket.isClosed()) {
                return;
            }
            try {
                byte[] bytes = message.getBytes();
                DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, this.address);
                datagramSocket.send(datagramPacket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    static void setTarget(File file) {
        setTarget(file, false);
    }

    static void setTarget(File file, boolean append) {
        try {
            LogCat.printer = new PrintWriterPrinter(new PrintWriter(new FileWriter(file, append), true));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void setTarget(String ip, int port) {
        setTarget(new InetSocketAddress(ip, port));
    }

    static void setTarget(SocketAddress socketAddress) {
        LogCat.printer = new MyPrinter(socketAddress);
    }

    /**
     * 指定 日志级别和标签 普通打印
     */
    static void setTarget(int priority, String tag) {
        LogCat.printer = new LogPrinter(priority, tag);
    }

}